/*
 * Viewer.java
 *
 * Created on June 18, 2008, 10:23 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package levelbuilder;

/**
 *
 * @author ew562c
 */
import java.awt.*;
import java.awt.event.*;
import java.util.Vector;
import javax.swing.*;

public class Viewer extends JPanel implements ActionListener, ItemListener{
        private Vector wallList;
        WallObject bone;
        WallObject home;
        
        WallObject selected_obj;
        WallObject copy_obj;
        
        MediaTracker mediaTracker;
        final JPopupMenu no_select_pop;
        JMenuItem AddWallMenuItem;
        JMenuItem AddBoneMenuItem;
        JMenuItem AddHomeMenuItem;
        JMenuItem DeleteMenuItem;
        JMenuItem ResetMenuItem;
        
        JMenuItem CopyMenuItem;
        JMenuItem PasteMenuItem;
        
        int pX, pY;
        boolean isDragging = false;
        Point start_point;
        int offset_x;
        int offset_y;
        
        String base_image_path = "/operation/images";
        String wall_image_name = "wall.png";
        String bone_image_name = "bone.png";
        String home_image_name = "home.png"; 
        
        
	public Viewer() {
                //this.setResizable(false);
            
                no_select_pop = new JPopupMenu();
                
                AddWallMenuItem = new JMenuItem("Add_Wall");
                AddHomeMenuItem = new JMenuItem("Add_Home");
                AddBoneMenuItem = new JMenuItem("Add_Bone");
                DeleteMenuItem  = new JMenuItem("Delete");
                ResetMenuItem   = new JMenuItem("Reset");
                CopyMenuItem  = new JMenuItem("Copy");
                PasteMenuItem   = new JMenuItem("Paste");
                
                DeleteMenuItem.setEnabled(false);
                ResetMenuItem.setEnabled(false);
                CopyMenuItem.setEnabled(false);
                PasteMenuItem.setEnabled(false);
             //   no_select_pop.add
                
                AddWallMenuItem.addActionListener(this);
                AddHomeMenuItem.addActionListener(this);
                AddBoneMenuItem.addActionListener(this);
                DeleteMenuItem.addActionListener(this);
                ResetMenuItem.addActionListener(this);
                CopyMenuItem.addActionListener(this);
                PasteMenuItem.addActionListener(this);
                
                no_select_pop.add((AddWallMenuItem));
                no_select_pop.add((AddHomeMenuItem));
                no_select_pop.add((AddBoneMenuItem));
                no_select_pop.addSeparator();
                no_select_pop.add((CopyMenuItem));
                no_select_pop.add((PasteMenuItem));
                no_select_pop.addSeparator();
                no_select_pop.add((DeleteMenuItem));
                no_select_pop.add((ResetMenuItem));
                
                MouseMotionListener control = new MouseMotionListener(){
                    public void mouseMoved(MouseEvent e)
                    {
                        
                    }
                    
                    public void mouseDragged(MouseEvent e)
                    {
                        //Move
                        if(!isDragging && selected_obj != null)
                        {
                            start_point = e.getPoint();
                            offset_x = (int)e.getPoint().getX() - selected_obj.GetX();
                            offset_y = (int)e.getPoint().getY() - selected_obj.GetY();
                        }
                        
                        if(!(e.isControlDown()) && !(e.isShiftDown()) && selected_obj != null)
                        {
                            selected_obj.SetPosition(e.getX()-offset_x, e.getY()-offset_y);
                            repaint();
                        }
                        //Resize
                        if(e.isShiftDown() && selected_obj != null)
                        {
                         
                            double startDist = start_point.distance(selected_obj.GetX(), selected_obj.GetY());
                            double curDist   = e.getPoint().distance(selected_obj.GetX(), selected_obj.GetY());
                            
                            double zoom = curDist/startDist;
                            zoom = Math.rint(zoom*100.0)/100.0;
                            
                            selected_obj.SetZoom(zoom);
                            repaint();
                        }
                        //Rotate
                        if(e.isControlDown() && selected_obj != null)
                        {
                            double startDist = start_point.distance(selected_obj.GetX(), selected_obj.GetY());
                            double curDist   = e.getPoint().distance(selected_obj.GetX(), selected_obj.GetY());
                            
                            double rotation = (360.0*(curDist/startDist)) % 360.0;
                            
                            rotation = Math.rint(rotation*100.0)/100.0;
                            
                            selected_obj.SetRotation(rotation);
                            repaint();
                        }
                        isDragging = true;
                        
                    }

                };
                
                
                
                MouseListener popup = new MouseListener() {
                  public void mouseClicked(MouseEvent e) {
                  }
                    
                    public void mouseEntered(MouseEvent e) {
                  }

                  public void mouseExited(MouseEvent e) {
                  }

                  public void mousePressed(MouseEvent e) { 
                        if(!(e.isControlDown()) && !(e.isAltDown()) && !(e.isShiftDown()))
                        {
                            
                            SetSelected(e.getX(), e.getY());
                            
                            if(selected_obj != null)
                            {
                                ResetMenuItem.setEnabled(true);
                                DeleteMenuItem.setEnabled(true);
                            }
                            else
                            {
                                DeleteMenuItem.setEnabled(false);
                                ResetMenuItem.setEnabled(false);
                            }
                            repaint();
                        }
                        
                    if (e.isPopupTrigger()) {
                      showPopup(e);
                    }
                    
                    
                  }

                  public void mouseReleased(MouseEvent e) {
                    isDragging = false;
                    if (e.isPopupTrigger()) {
                      showPopup(e);
                    }
                  }

                  private void showPopup(MouseEvent e) {
                      pX = e.getX();
                      pY = e.getY();
                      no_select_pop.show(e.getComponent(), e.getX(), e.getY());
                  }
                };
                
                addMouseListener(popup);
                addMouseMotionListener(control);
                wallList = new Vector();
                wallList.clear();
		mediaTracker = new MediaTracker(this);

		setSize(640, 480);
	//	setTitle(level_name);
		setVisible(true);
	}
        
        public void SetBaseImagePath(String img){base_image_path = img;}
        public String GetBaseImagePath(){return base_image_path;}
        
        public WallObject GetBone(){return bone;}
        public WallObject GetHome(){return home;}
        public int GetWallCount(){return wallList.size();}
        public WallObject GetWall(Integer i){return (WallObject)wallList.get(i);}
        
        public void SetBoneImage(String i)
        {
            bone_image_name = i;
        }
        
        public void SetHomeImage(String i)
        {
            home_image_name = i;
        }
        
        public void SetWallImage(String i)
        {
            wall_image_name = i;
        }
        
        public void UpdateImages()
        {
	   Toolkit toolkit = Toolkit.getDefaultToolkit();
           Image image;
           
           if(bone != null)
               bone.SetImage(toolkit.getImage(GetBaseImagePath()+"/"+GetBoneImage()));

           if(home != null)
               home.SetImage(toolkit.getImage(GetBaseImagePath()+"/"+GetHomeImage()));
           
           image = toolkit.getImage(GetBaseImagePath()+"/"+GetWallImage());
           
            for(int i = 0; i < wallList.size(); i++)
            {
               WallObject tobj = (WallObject)wallList.get(i);
               tobj.SetImage(image);
            }
            repaint();
        }
        
        public String GetBoneImage()
        {
            return bone_image_name;
        }
        
        public String GetHomeImage()
        {
            return home_image_name;
        }
        
        public String GetWallImage()
        {
            return wall_image_name;
        }
        
        public void ClearAll()
        {
                selected_obj = null;  
                wallList.clear();
                bone = null;
                home = null;
                repaint();
        }
        
        public void DeleteSelected()
        {
            if(selected_obj != null)
            {
                for(int i = 0; i < wallList.size(); i++)
                {
                   WallObject tobj = (WallObject)wallList.get(i);
                   if(tobj == selected_obj)
                   {
                       wallList.remove(i);
                       break;
                   }
                }

                if(bone != null && selected_obj != null)
                {
                   if(bone == selected_obj)
                       bone = null;
                }

                if(home != null && selected_obj != null)
                {
                   if(home == selected_obj)
                       home = null;
                }
                selected_obj = null;
            }
            repaint();
        }
        
        public void SetSelected(Integer x, Integer y)
        {
            selected_obj = null;
            this.CopyMenuItem.setEnabled(false);
        
            for(int i = 0; i < wallList.size(); i++)
            {
               WallObject tobj = (WallObject)wallList.get(i);
               if(tobj.Select(x, y))
               {
                  this.CopyMenuItem.setEnabled(true);
                   selected_obj = tobj;
               }
            }

            if(bone != null)
            {
               if(bone.Select(x, y))
                   selected_obj = bone;
            }

            if(home != null)
            {
               if(home.Select(x, y))
                   selected_obj = home;
            }
    }
    
    public void actionPerformed(ActionEvent e) {
        //...Get information from the action event...
        //...Display it in the text area...
        if(e.getActionCommand().equalsIgnoreCase("Add_Wall"))
        {
            addWall(GetBaseImagePath()+"/"+GetWallImage(), pX,pY,0.0,1.0);
        }
        else if(e.getActionCommand().equalsIgnoreCase("Add_Home"))
        {
            addHome(GetBaseImagePath()+"/"+GetHomeImage(), pX,pY,0.0,1.0);
            repaint();
        }
        else if(e.getActionCommand().equalsIgnoreCase("Add_Bone"))
        {
            addBone(GetBaseImagePath()+"/"+GetBoneImage(), pX,pY,0.0,1.0);
        }
        else if(e.getActionCommand().equalsIgnoreCase("Delete"))
        {
            DeleteSelected();
        }
        else if(e.getActionCommand().equalsIgnoreCase("Reset"))
        {
            if(selected_obj != null) selected_obj.Reset();
        }
        else if(e.getActionCommand().equalsIgnoreCase("Copy"))
        {
            if(selected_obj != null)
            {
                copy_obj = selected_obj;
                this.PasteMenuItem.setEnabled(true);
            }
        }
        else if(e.getActionCommand().equalsIgnoreCase("Paste"))
        {
            if(copy_obj != null)
            {
                addWall(GetBaseImagePath()+"/"+GetWallImage(), pX,pY,copy_obj.GetRotation(),copy_obj.GetZoom());
            }
        }
        repaint();
    }

    public void itemStateChanged(ItemEvent e) {
        //...Get information from the item event...
        //...Display it in the text area...
    }
    
    
        public void addHome(String filename, Integer x, Integer y, Double rot, Double zoom)
        {
		Toolkit toolkit = Toolkit.getDefaultToolkit();
                
		Image image = toolkit.getImage(filename);

		mediaTracker.addImage(image, 0);
                //mediaTracker.
                home = new WallObject(image);
                home.SetPosition(x,y);
                home.SetRotation(rot);
                home.SetZoom(zoom);
		try
		{
			mediaTracker.waitForID(0);
		}
		catch (InterruptedException ie)
		{
			System.err.println(ie);
			System.exit(1);
		}
                repaint();
                
        }
        
        public void addBone(String filename, Integer x, Integer y, Double rot, Double zoom)
        {
		Toolkit toolkit = Toolkit.getDefaultToolkit();
                
		Image image = toolkit.getImage(filename);
		mediaTracker.addImage(image, 0);
                
                bone = new WallObject(image);
                bone.SetPosition(x,y);
                bone.SetRotation(rot);
                bone.SetZoom(zoom);
		try
		{
			mediaTracker.waitForID(0);
		}
		catch (InterruptedException ie)
		{
			System.err.println(ie);
			System.exit(1);
		}
                repaint();
        }
    
        public void addWall(String filename, Integer x, Integer y, Double rot, Double zoom)
        {
		Toolkit toolkit = Toolkit.getDefaultToolkit();
                
		Image image = toolkit.getImage(filename);
		mediaTracker.addImage(image, 0);
                
                WallObject obj = new WallObject(image);
                obj.SetPosition(x,y);
                obj.SetRotation(rot);
                obj.SetZoom(zoom);
		try
		{
			mediaTracker.waitForID(0);
		}
		catch (InterruptedException ie)
		{
			System.err.println(ie);
			System.exit(1);
		}
                wallList.add(obj);
                repaint();
        }
        
	public void paint(Graphics graphics) {
                //Draw Walls
                graphics.setColor(Color.BLACK);
                graphics.clearRect(0, 0, 640, 480);  
                graphics.fillRect(0,0,640,480);
            
                for(int i = 0; i < wallList.size(); i++)
                {
                   WallObject tobj = (WallObject)wallList.get(i);
		   graphics.drawImage(tobj.GetImage(), tobj.GetOffsetX(), tobj.GetOffsetY(), null);
                }
                
                if(bone != null)
                {
		   graphics.drawImage(bone.GetImage(), bone.GetOffsetX(), bone.GetOffsetY(), null);             
                }   
                if(home != null)
                {
		   graphics.drawImage(home.GetImage(), home.GetOffsetX(), home.GetOffsetY(), null);   
                   
                }
                
                //draw selected
                if(selected_obj != null)
                {
                   graphics.setColor(Color.blue);
                   graphics.drawRect(selected_obj.GetX()-30, selected_obj.GetY()-30,selected_obj.GetObjWidth()+60, selected_obj.GetObjHeight()+60);   
                }
        }
}